﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace STSdb.MTL
{
    public class TableCompactingResult
    {

        public TableCompactingResult()
        {
            RealTableName = String.Empty;
            CompactedTableName = String.Empty;
            Compacted = false;
            RFS_After = 0;
            RFS_Before = 0;
            TS_After = 0;
            TS_Before = 0;            
            RecordsCount = 0;
            CompacterIsBusy = false;
            CompacterError = false;
        }

        public string ToConsoleString()
        {
            //return base.ToString();

            return String.Format(""
                + "RTN: {0}; CTN: {1}; C: {2}; "
                + "RFSB: {3:#,#0.#}; RFSA: {4:#,#0.#}; "
                + "TSB: {5:#,#0.#}; TSA: {6:#,#0.#}; "
                + "WSB: {7:#,#0.#}; WSA: {8:#,#0.#}; "
                + "WSB_T: {9:#,#0.#} %; WSA_T: {10:#,#0.#} %; "
                + "WSB_RF: {11:#,#0.#} %; WSA_RF: {12:#,#0.#} %; "
                + "BPR_b_RF: {13:#,#0.#}; BPR_a_RF: {14:#,#0.#}; "
                + "BPR_b_T: {15:#,#0.#}; BPR_a_T: {16:#,#0.#}; "
                + "CNT {17:#,#0.#}; "

                , RealTableName,CompactedTableName,(Compacted) ? 1 : 0
                , RFS_Before, RFS_After
                , TS_Before, TS_After
                , WastedSpace_Before, WastedSpace_After
                , WastedSpace_Before_WvsT_procent,WastedSpace_After_WvsT_procent
                , WastedSpace_Before_WvsRF_procent,WastedSpace_After_WvsRF_procent
                , RF_BytesPerRecord_Before, RF_BytesPerRecord_After
                , TS_BytesPerRecord_Before,TS_BytesPerRecord_After
                , RecordsCount
                );
        }

        public string ToCsvString()
        {
            //return base.ToString();

            return String.Format(""
                + ";;{2};"
                + "{3};{4};" 
                + "{5};{6};"
                + "{7};{8};"
                + "{9};{10};"
                + "{11};{12};"
                + "{13};{14};"
                + "{15};{16};"
                + "{17};"

                , RealTableName, CompactedTableName, (Compacted) ? 1 : 0
                , RFS_Before, RFS_After
                , TS_Before, TS_After
                , WastedSpace_Before, WastedSpace_After
                , WastedSpace_Before_WvsT_procent, WastedSpace_After_WvsT_procent
                , WastedSpace_Before_WvsRF_procent, WastedSpace_After_WvsRF_procent
                , RF_BytesPerRecord_Before, RF_BytesPerRecord_After
                , TS_BytesPerRecord_Before, TS_BytesPerRecord_After
                , RecordsCount
                );
        }

        public string RealTableName { get; set; }
        public string CompactedTableName { get; set; }



        /// <summary>
        /// Indicated that record was compacted
        /// </summary>
        public bool Compacted { get; set; }

        /// <summary>
        /// Indicates that compactor was busy
        /// </summary>
        public bool CompacterIsBusy { get; set; }

        /// <summary>
        /// Indicates that InCompacter error has occured
        /// </summary>
        public bool CompacterError { get; set; }

        private Exception _CompacterException = null;
        /// <summary>
        /// If Compacter has an exception it will be reflected here,
        /// <para>Automatically CompacterError will be set to true</para>
        /// </summary>
        public Exception CompacterException
        {
            get { return this._CompacterException; }
            set
            {
                CompacterError = true;
                this._CompacterException = value;
            }
        }


        /// <summary>
        /// Raw File Size before compacting
        /// </summary>
        public ulong RFS_Before { get; set; }

        /// <summary>
        /// Raw File Size after compacting
        /// </summary>
        public ulong RFS_After { get; set; }

        /// <summary>
        /// Table size before compacting
        /// </summary>
        public ulong TS_Before { get; set; }

        /// <summary>
        /// Table size after compacting
        /// </summary>
        public ulong TS_After { get; set; }

        /// <summary>
        /// Wasted Space before compacting = Raw File Size before - Table Size before
        /// </summary>
        public ulong WastedSpace_Before
        {
            get
            {
                return RFS_Before - TS_Before;
            }
        }

        /// <summary>
        /// Wasted Space after compacting = Raw File Size after - Table Size after
        /// </summary>
        public ulong WastedSpace_After
        {
            get
            {
                return RFS_After - TS_After;
            }
        }

        /// <summary>
        /// Wasted space before compacting = Wasted Space Before / Table Size Before
        /// </summary>
        public int WastedSpace_Before_WvsT_procent
        {
            get
            {
                return Convert.ToInt32((TS_Before == 0) ? 0 : (WastedSpace_Before * 100) / TS_Before);
            }
        }

        /// <summary>
        /// Wasted space after compacting =  Wasted Space After / Table Size After
        /// </summary>
        public int WastedSpace_After_WvsT_procent
        {
            get
            {
                return Convert.ToInt32((TS_After == 0) ? 0 : (WastedSpace_After * 100) / TS_After);
            }
        }

        /// <summary>
        /// Wasted space before compacting = Wasted Space Before / Raw File Size Before in procent
        /// </summary>
        public int WastedSpace_Before_WvsRF_procent
        {
            get
            {
                return Convert.ToInt32((RFS_Before == 0) ? 0 : (WastedSpace_Before * 100) / RFS_Before);
            }
        }

        /// <summary>
        /// Wasted space after compacting = Wasted Space After / Raw File Size After in procent
        /// </summary>
        public int WastedSpace_After_WvsRF_procent
        {
            get
            {
                return Convert.ToInt32((RFS_After == 0) ? 0 : (WastedSpace_After * 100) / RFS_After);
            }
        }


        /// <summary>
        /// Quantity of records in the table
        /// </summary>
        public ulong RecordsCount { get; set; }
               
        /// <summary>
        /// Quantity of bytes per record = RFS_Before/RecordsCount before compacting
        /// </summary>
        public ulong RF_BytesPerRecord_Before
        {
            get
            {
                return (RecordsCount == 0) ? 0 : RFS_Before / RecordsCount;
            }
        }
               
        /// <summary>
        /// Quantity of bytes per record = RFS_After/RecordsCount before compacting
        /// </summary>
        public ulong RF_BytesPerRecord_After
        {
            get
            {
                return (RecordsCount == 0) ? 0 : RFS_After / RecordsCount;
            }
        }

        /// <summary>
        /// Quantity of bytes per record = TS_Before/RecordsCount before compacting
        /// </summary>
        public ulong TS_BytesPerRecord_Before
        {
            get
            {
                return (RecordsCount == 0) ? 0 : TS_Before / RecordsCount;
            }
        }

        /// <summary>
        /// Quantity of bytes per record = TS_Before/RecordsCount before compacting
        /// </summary>
        public ulong TS_BytesPerRecord_After
        {
            get
            {
                return (RecordsCount == 0) ? 0 : TS_After / RecordsCount;
            }
        }


        public enum CompactingStartegies
        {
            Compact_When_WastedToTableSize_ExceedsPercentage,
            Compact_When_WastedToRawFileSize_ExceedsPercentage            
        }


        /// <summary>
        /// Returns true if choosen compaction strategy satisfies conditions
        /// </summary>
        /// <param name="compactingStrategy"></param>
        /// <param name="exceedingPercentage"></param>
        /// <returns></returns>
        public bool If_To_Compact_ByExccedingPercentage(CompactingStartegies compactingStrategy, int exceedingPercentage)
        {
            switch (compactingStrategy)
            {
                case CompactingStartegies.Compact_When_WastedToTableSize_ExceedsPercentage:
                    return (WastedSpace_Before_WvsT_procent > exceedingPercentage);
                case CompactingStartegies.Compact_When_WastedToRawFileSize_ExceedsPercentage:
                    return (WastedSpace_Before_WvsRF_procent > exceedingPercentage);
                default:
                    return false;
            }

        }

    }
}
